package com.addzero.web.ui.system.hooks.side_menu

import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import com.addzero.common.kt_util.isBlank
import com.addzero.common.kt_util.isNotBlank
import com.addzero.common.util.data_structure.predicate.ex.TreePredicateBuilder
import com.addzero.web.ui.components.ScrollableContainer
import com.addzero.web.ui.hooks.UseHook
import com.addzero.web.ui.hooks.tree.NodeTypes
import com.addzero.web.ui.hooks.tree.UseListTree
import com.addzero.web.ui.system.dynamicroute.RouteMetadata
import com.addzero.web.ui.system.dynamicroute.RouteUtil
import com.addzero.web.ui.system.hooks.renderNaviItem

fun routeToTree(allRoutes: List<RouteMetadata>): Pair<List<RouteMetadata>, Map<String, RouteMetadata>> {
    // 创建一个映射，用于快速查找路由
    val routeMap = allRoutes.associateBy { it.routerPath }

    // 创建一个可变的路由列表副本，以便我们可以修改children属性
    val mutableRoutes = allRoutes.map { it.copy(children = emptyList()) }.toMutableList()

    // 创建一个映射，用于快速查找路由(按title索引)
    val routesByTitle = mutableRoutes.associateBy { it.title }.toMutableMap()

    // 存储根节点（没有父节点的路由）
    val rootNodes = mutableListOf<RouteMetadata>()

    // 第一遍：确定所有节点的父子关系
    mutableRoutes.forEach { route ->
        val parentName = route.parentName

        if (parentName == null || parentName.isBlank() || !routesByTitle.containsKey(parentName)) {
            // 如果没有父节点，或父节点不存在，则为根节点
            rootNodes.add(route)
        } else {
            // 查找父节点
            val parentNode = routesByTitle[parentName]

            // 如果找到父节点，将当前节点添加到父节点的children列表中
            parentNode?.let {
                val updatedChildren = it.children + route
                val updatedParent = it.copy(children = updatedChildren)

                // 更新映射中的父节点
                routesByTitle[parentName] = updatedParent
            }
        }
    }

    // 第二遍：递归更新所有节点的children列表
    fun updateNodeChildrenRecursive(nodes: List<RouteMetadata>): List<RouteMetadata> {
        return nodes.map { node ->
            // 获取最新版本的节点（可能已经被更新过）
            val updatedNode = routesByTitle[node.title] ?: node

            if (updatedNode.children.isNotEmpty()) {
                // 递归更新子节点
                val updatedChildren = updateNodeChildrenRecursive(updatedNode.children)
                updatedNode.copy(children = updatedChildren)
            } else {
                updatedNode
            }
        }
    }

    // 更新根节点及其所有子节点
    val finalRootNodes = updateNodeChildrenRecursive(rootNodes)

    // 排序根节点
    val sortedRootNodes = finalRootNodes.sortedBy { it.order }

    return sortedRootNodes to routeMap
}

private fun getPidByPNam(
    metadata1: RouteMetadata,
    associateBy: Map<String, RouteMetadata>,
): String? {
    val parentName = metadata1.parentName
    val metadata = associateBy[parentName]
    val routerPath = metadata?.routerPath
    return routerPath
}

fun searchRoute(
    keyword: String, routes: List<RouteMetadata>, dict: Map<String, RouteMetadata>,
    otherFilter: (RouteMetadata) -> Boolean,
): List<RouteMetadata> {
    if (keyword.isBlank()) {
        return routes
    }
    val like1 = TreePredicateBuilder.lambdaQuery(
        routes,
        {
            val pidByPNam = getPidByPNam(it, dict)
            val blank = pidByPNam.isBlank()
            blank
        },
        {
            it.routerPath
        },
        getPid = {
            val pidByPNam = getPidByPNam(it, dict)
            pidByPNam
        },
        getChildren = { it.children },
        setChildren = { e, routes -> e.children = routes },
    ).like(keyword.isNotBlank(), { it.title }, keyword)
    val treeSonAndFather = like1.treeSonAndFather()
    val like = like1.treeSonAndFather()


//    val value = like.and { otherFilter(it) }
    return like

}

/**
 * 侧边菜单Hook
 */
class UseSideMenu() : UseHook<UseSideMenu> {
    // 搜索查询
    var keyword by mutableStateOf("")

    // 所有路由
    val allTree by lazy {
        val allRoute = RouteUtil.getAllRoute()
        val pair = routeToTree(allRoute)
        val first = pair
        first
    }
        val searchRoute = searchRoute(keyword, allTree.first, allTree.second, otherFilter = { true })


    //    lis
//    allRoutes.totree

    // 直接使用路由树作为初始数据
    var treeData by mutableStateOf(searchRoute)

    // 管理哪些节点是展开的
    var expandedNodes by mutableStateOf(setOf<String>())
        private set

    // 添加一个刷新计数器，用于强制重新渲染
    private var refreshCounter by mutableStateOf(0)

    // 切换节点展开状态的函数
    fun toggleNodeExpansion(nodePath: String) {
        expandedNodes = if (expandedNodes.contains(nodePath)) {
            expandedNodes - nodePath
        } else {
            expandedNodes + nodePath
        }

        // 增加刷新计数器，强制重新渲染
        refreshCounter++
    }

    // 强制刷新方法
    fun forceRefresh() {
        // 增加刷新计数器，强制重新渲染
        refreshCounter++
    }

    // 搜索框
    // 当前选中的路由
    var currentRoute by mutableStateOf("")

    // 每次refreshCounter变化时，重新创建useListTree实例
    val useListTree = UseListTree(
        initialNodes = treeData,
        getIdFun = { it.routerPath },
        getChildren = { it.children },
        getLaebel = { it.title },
        getNodeTypeFun = {
            when {
                // 有子节点的是菜单
                it.children.isNotEmpty() -> NodeTypes.MENU
                // 没有子节点，但有实现类或函数的是页面
                it.clazz != null || it.func != null -> NodeTypes.PAGE
                // 默认作为文件夹类型
                else -> NodeTypes.FOLDER
            }
        })
        .apply {
            useTreeNodeItem.customRender = { meta ->
                val isSelected = meta.routerPath == currentRoute
                val hasChildren = meta.children.isNotEmpty()

                // 为每个UseTreeNodeItem实例提供其对应的节点是否应该展开的信息
                if (hasChildren) {
                    val nodeId = meta.routerPath
                    val shouldExpand = expandedNodes.contains(nodeId)
                    useTreeNodeItem.expanded = shouldExpand
                }

                // 默认情况下使用完全展开的渲染
                renderNaviItem(this@UseSideMenu, meta, isSelected, hasChildren)
            }
        }

    // 实现新的renderWithParams方法，支持可变参数
//    @Composable

    // 原始渲染函数，向后兼容
    override val render: @Composable () -> Unit = {
        // 调用带参数的渲染函数，默认完全展开
        ScrollableContainer(
            showScrollbar = true,
            modifier = Modifier.fillMaxWidth()
        ) {
            // 传递展开状态到渲染函数
            useListTree.apply {
                useTreeNodeItem.apply {
                    // 设置是否显示文本的标志
                    customRender = { meta ->
                        val isSelected = meta.routerPath == currentRoute
                        val hasChildren = meta.children.isNotEmpty()

                        // 更新节点展开状态
                        if (hasChildren) {
                            val nodeId = meta.routerPath
                            val shouldExpand = expandedNodes.contains(nodeId)
                            this.expanded = shouldExpand
                        }

                        // 调用渲染函数，传递额外的isExpanded参数
                        renderNaviItem(this@UseSideMenu, meta, isSelected, hasChildren)
                    }
                }
            }.render {}
        }

    }
}
